home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Mac Game Programming Gurus / TricksOfTheMacGameProgrammingGurus.iso / Demos / Tools / QC™ 1.1.3 / QCAPI / BadAPPL / BadAPPL src / BadWindows.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-04-21  |  10.0 KB  |  396 lines  |  [TEXT/R*ch]

  1. /*________________________________________________________________________________
  2.     BadWindows.c
  3.  
  4.     Copyright © 1993-1995 Onyx Technology - All rights reserved
  5.  
  6.     Routines to handle the text window displaying a status of what BadAPPL
  7.     is doing.
  8. ________________________________________________________________________________*/
  9.  
  10. #ifndef    _H_BadAPPL
  11. #include "BadAPPL.h"
  12. #endif
  13. #ifndef    _H_BadWindows
  14. #include "BadWindows.h"
  15. #endif
  16. #ifndef    _H_BadUtils
  17. #include "BadUtils.h"
  18. #endif
  19. #ifndef    _H_BadGlobs
  20. #include "BadGlobs.h"
  21. #endif
  22.  
  23. //    Prototypes for private functions.
  24. static void AdjustText (void);
  25. static void SetVScroll(void);
  26. static void SetView (WindowPtr w);
  27. static pascal void ScrollProc (ControlHandle theControl, short theCode);
  28.  
  29. // This #define is in Universal Headers so we can use it to determine if
  30. //    we need ControlActionUPP defined or if it's already available.
  31. #ifndef    OLDROUTINENAMES
  32. typedef    ProcPtr ControlActionUPP;
  33. #endif
  34.  
  35. void SetUpWindows(void)
  36. {
  37.     Rect            viewRect;
  38.     Rect            vScrollRect;
  39.  
  40.     gStatusWindow = GetNewWindow(kTestWindowID, 0L, (WindowPtr) -1L);
  41.     if (gStatusWindow)
  42.         {
  43.         SetPort(gStatusWindow);
  44.         TextFont(monaco);
  45.         TextSize(9);
  46.         vScrollRect = (*gStatusWindow).portRect;
  47.         vScrollRect.left = vScrollRect.right-15;
  48.         vScrollRect.right += 1;
  49.         vScrollRect.bottom -= 14;
  50.         vScrollRect.top -= 1;
  51.         gVScroll = NewControl( gStatusWindow, &vScrollRect, "\p", 1, 0, 0, 0,
  52.             scrollBarProc, 0L);
  53.     
  54.         viewRect = qd.thePort->portRect;
  55.         viewRect.right -= SBarWidth;
  56.         viewRect.bottom -= SBarWidth;
  57.         InsetRect(&viewRect, 4, 4);
  58.         gTEH = TENew(&viewRect, &viewRect);
  59.     
  60.         SetView(qd.thePort);
  61.         }
  62.     else
  63.         {DbugStr("\pGetNewWindow failed!");}
  64. }
  65.  
  66.  
  67. /*________________________________________________________________________________
  68.  
  69.     OutputString()
  70.  
  71.     info:     Output a given string to the status window
  72.             Note there is no status of whether the string was displayed or
  73.             an error occured.  It either makes it or it doesnt.
  74.  
  75.     entry:    strID    -    id of the STR# resource to get the string from
  76.             indxID    -    index into the STR# resource
  77.  
  78. ________________________________________________________________________________*/
  79.  
  80. void    OutputString(short strID, short indxID, long theAddr)
  81. {
  82.     Str255    string;
  83.     Str255    tempStr;
  84.     long    finalTicks;
  85.     THz        savedZone;
  86.  
  87.     savedZone    =     GetZone();
  88.     SetZone(gAppHeap);                                // make sure we use the BadAPPL zone
  89.  
  90.     GetIndString(string, strID, indxID);            // get the appropriate string
  91.  
  92.     if (theAddr)                                    // is there an address to add in?
  93.         {
  94.         HexToString(theAddr, tempStr);                // yes, convert it to a string
  95.         AppendString(string, tempStr);                // and add it to the overall string
  96.         }
  97.  
  98.     if (gTEH && (string[0] > 0))                        // do we have gTEH and a string?
  99.         {
  100.         CheckTextSize();                            // make sure we dont overflow gTEH
  101.         TEInsert((Ptr) &string[1], string[0], gTEH);    // push it into the TE record
  102.         TEKey( 0x0D, gTEH);                            // and a return
  103.         ShowSelect();                                // and redraw everything if needed.
  104.         }
  105.  
  106.     Delay((long) 30, &finalTicks);                    // lets pause so the user can read this
  107.  
  108.     SetZone(savedZone);                                // restore the previous zone
  109. }
  110.  
  111. /*________________________________________________________________________________
  112.  
  113.     AdjustText()
  114.  
  115.     info:     adjust the text in the gTEH record making sure we are scrolling
  116.             if needed.
  117.  
  118. ________________________________________________________________________________*/
  119. static void AdjustText(void)
  120. {
  121.     short        oldScroll, newScroll, delta;
  122.     
  123.     oldScroll = (**gTEH).viewRect.top - (**gTEH).destRect.top;
  124.     newScroll = GetCtlValue(gVScroll) * (**gTEH).lineHeight;
  125.     delta = oldScroll - newScroll;
  126.     if (delta != 0)
  127.       TEScroll(0, delta, gTEH);
  128. }
  129.  
  130. /*________________________________________________________________________________
  131.  
  132.     CheckTextSize()
  133.  
  134.     info:     Check the size of the text edit record and dont let it get too
  135.             big!  If it grows past 2k, then start cutting text away at the
  136.             top 100 bytes at a time.
  137.  
  138. ________________________________________________________________________________*/
  139. void CheckTextSize (void)
  140. {
  141.     if ((**gTEH).teLength >= 2048)                // are we bigger than 2k?
  142.         {
  143.         TESetSelect( 0, 100, gTEH);                // set the selection range we want
  144.         TEDelete(gTEH);                            //    then chop off the first 100 bytes
  145.                                                 // adjust the selection/insertion point
  146.         TESetSelect( 32768, 32768, gTEH);        //     by using an out of bounds limit
  147.                                                 //     TextEdit will politely place us
  148.                                                 //     at the end of the text.
  149.         }
  150. }
  151.  
  152.  
  153. /*________________________________________________________________________________
  154.  
  155.     SetVScroll()
  156.  
  157.     info:     set the vertical scroll bar to the correct value.
  158.  
  159. ________________________________________________________________________________*/
  160. static void SetVScroll(void)
  161. {
  162.     register short    n;
  163.     
  164.     n = (**gTEH).nLines-gLinesInStatus;
  165.  
  166.     if ((**gTEH).teLength > 0 && (*((**gTEH).hText))[(**gTEH).teLength-1]=='\r')
  167.         n++;
  168.  
  169.     SetCtlMax(gVScroll, n > 0 ? n : 0);
  170. }
  171.  
  172. /*________________________________________________________________________________
  173.  
  174.     ShowSelect()
  175.  
  176.     info:     update the text displayed in the gTEH record
  177.  
  178. ________________________________________________________________________________*/
  179. void ShowSelect (void)
  180. {
  181.     TEPtr        teP;
  182.     register    short        topLine, bottomLine, theLine;
  183.     
  184.     SetVScroll();
  185.     AdjustText();
  186.     
  187.     topLine = GetCtlValue(gVScroll);
  188.     bottomLine = topLine + gLinesInStatus;
  189.  
  190.     HLock((Handle)gTEH);
  191.     teP = *gTEH;
  192.     if ((teP->selStart < teP->lineStarts[topLine]) ||
  193.         (teP->selStart >= teP->lineStarts[bottomLine]))
  194.         {
  195.         for (theLine = 0; teP->selStart >= teP->lineStarts[theLine]; theLine++);
  196.         SetCtlValue(gVScroll, theLine - gLinesInStatus / 2);
  197.         AdjustText();
  198.     }
  199.     HUnlock((Handle)gTEH);
  200.  
  201. }
  202.  
  203. /*________________________________________________________________________________
  204.  
  205.     SetView()
  206.  
  207.     info:     update the viewing area of the gTEH record and recalc the text
  208.             boundaries.
  209.  
  210. ________________________________________________________________________________*/
  211. static void SetView (WindowPtr w)
  212. {
  213.     TEPtr        teP;
  214.  
  215.     HLock((Handle)gTEH);
  216.     teP = *gTEH;
  217.  
  218.     teP->viewRect = w->portRect;
  219.     teP->viewRect.right -= SBarWidth;
  220.     teP->viewRect.bottom -= SBarWidth;
  221.     InsetRect(&teP->viewRect, 4, 4);
  222.  
  223.     gLinesInStatus = (teP->viewRect.bottom-teP->viewRect.top)/teP->lineHeight;
  224.     teP->viewRect.bottom = teP->viewRect.top + teP->lineHeight*gLinesInStatus;
  225.     teP->destRect.right = teP->viewRect.right;
  226.     HUnlock((Handle)gTEH);
  227.  
  228.     TECalText(gTEH);
  229. }
  230.  
  231. /*________________________________________________________________________________
  232.  
  233.     UpdateWindow()
  234.  
  235.     info:     update our text edit status window
  236.  
  237. ________________________________________________________________________________*/
  238. void UpdateWindow (WindowPtr theWindow)
  239. {
  240.     GrafPtr    savePort;
  241.     
  242.     GetPort(&savePort);
  243.     SetPort(theWindow);
  244.  
  245.     BeginUpdate(theWindow);
  246.     EraseRect(&theWindow->portRect);
  247.     DrawControls(theWindow);
  248.     DrawGrowIcon(theWindow);
  249.     TEUpdate(&theWindow->portRect, gTEH);
  250.     EndUpdate(theWindow);
  251.  
  252.     SetPort(savePort);
  253. }
  254.  
  255.  
  256. /*________________________________________________________________________________
  257.  
  258.     ScrollProc()
  259.  
  260.     info:     the scrolling proc used in TrackControl call on the vertical
  261.             scroll bar.
  262.  
  263. ________________________________________________________________________________*/
  264. static pascal void ScrollProc (ControlHandle theControl, short theCode)
  265. {
  266.     short    pageSize;
  267.     short    scrollAmt;
  268.     short oldCtl;
  269.     
  270.     if (theCode == 0)
  271.         return ;
  272.     
  273.     pageSize = ((**gTEH).viewRect.bottom-(**gTEH).viewRect.top) / 
  274.             (**gTEH).lineHeight - 1;
  275.             
  276.     switch (theCode) {
  277.         case inUpButton: 
  278.             scrollAmt = -1;
  279.             break;
  280.         case inDownButton: 
  281.             scrollAmt = 1;
  282.             break;
  283.         case inPageUp: 
  284.             scrollAmt = -pageSize;
  285.             break;
  286.         case inPageDown: 
  287.             scrollAmt = pageSize;
  288.             break;
  289.     }
  290.  
  291.     oldCtl = GetCtlValue(theControl);
  292.     SetCtlValue(theControl, oldCtl+scrollAmt);
  293.  
  294.     AdjustText();
  295.  
  296. }
  297.  
  298. /*________________________________________________________________________________
  299.  
  300.     DoContent()
  301.  
  302.     info:     Handle a mouse down event in the content of our status window
  303.             Note that even though we are using a text edit record for the output
  304.             of the status strings, we do no allow editing of that record.
  305.  
  306. ________________________________________________________________________________*/
  307. void DoContent(WindowPtr theWindow, EventRecord *theEvent)
  308. {
  309.     short            cntlCode;
  310.     ControlHandle     theControl;
  311.     GrafPtr            savePort;
  312.     
  313.     GetPort(&savePort);
  314.     SetPort(theWindow);
  315.  
  316.     GlobalToLocal(&theEvent->where);
  317.     if ((cntlCode = FindControl(theEvent->where, theWindow, &theControl)) == 0)
  318.         {
  319.         #ifdef    _WE_WERE_EDITING_
  320.         if (PtInRect(theEvent->where, &(**gTEH).viewRect))
  321.             TEClick(theEvent->where, (theEvent->modifiers & shiftKey)!=0, gTEH);
  322.         #endif    //_WE_WERE_EDITING_
  323.         }
  324.     else if (cntlCode == inThumb)
  325.         {
  326.         TrackControl(theControl, theEvent->where, 0L);
  327.         AdjustText();
  328.         }
  329.     else
  330.         TrackControl(theControl, theEvent->where, (ControlActionUPP) &ScrollProc);
  331.  
  332.     SetPort(savePort);
  333. }
  334.  
  335. /*________________________________________________________________________________
  336.  
  337.     MyGrowWindow()
  338.  
  339.     info:     resize the status window according to the mouse point we kept
  340.             as the last coords for the resize.
  341.  
  342. ________________________________________________________________________________*/
  343. void MyGrowWindow(WindowPtr w, Point p)
  344. {
  345.     GrafPtr    savePort;
  346.     long    theResult;
  347.     Rect    oldHorizBar;
  348.     Rect     r;
  349.     
  350.     GetPort(&savePort);
  351.     SetPort(w);
  352.     
  353.     oldHorizBar = w->portRect;
  354.     oldHorizBar.top = oldHorizBar.bottom - (SBarWidth+1);
  355.  
  356.     SetRect(&r, 80, 80, qd.screenBits.bounds.right, qd.screenBits.bounds.bottom);
  357.     theResult = GrowWindow(w, p, &r);
  358.     if (theResult != 0)
  359.         {
  360.         SizeWindow( w, LoWord(theResult), HiWord(theResult), false);
  361.  
  362.         InvalRect(&w->portRect);
  363.     
  364.         SetView(w);
  365.  
  366.         EraseRect(&oldHorizBar);
  367.     
  368.         MoveControl(gVScroll, w->portRect.right - SBarWidth, w->portRect.top-1);
  369.         SizeControl(gVScroll, SBarWidth+1, w->portRect.bottom - w->portRect.top-(SBarWidth-2));
  370.         r = (**gVScroll).contrlRect;
  371.         ValidRect(&r);
  372.  
  373.  
  374.         SetVScroll();
  375.         AdjustText();
  376.     
  377.         SetPort(savePort);
  378.         }
  379. }
  380.  
  381. /*________________________________________________________________________________
  382.  
  383.     CloseMyWindow()
  384.  
  385.     info:     Lets hide our status window and get rid of the text edit
  386.             record we have been using.
  387.  
  388. ________________________________________________________________________________*/
  389. void CloseMyWindow(void)
  390. {
  391.     HideWindow(gStatusWindow);
  392.     TESetSelect(0, (**gTEH).teLength, gTEH);
  393.     TEDelete(gTEH);
  394.     SetVScroll();
  395. }
  396.